package com.budayi.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.ByteBufAllocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.InetSocketAddress;

/**
 * @author LIBOFEI
 * @ClassName GlobalLogFilter
 * @description 全局过滤器 -- 访问日志
 * @date 2021/4/25 23:58
 * @Version 1.0
 **/
@Component
public class GlobalLogFilter implements GlobalFilter, Ordered {

    private final ObjectMapper mapper = new ObjectMapper();

    private static Logger logger = LoggerFactory.getLogger(GlobalLogFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println("进入全局过滤器");
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().pathWithinApplication().value();
        HttpMethod method = request.getMethod();
        StringBuilder builder = new StringBuilder();
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        try {
            builder.append(mapper.writeValueAsString(queryParams));
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(), e);
        }
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        return chain.filter(exchange.mutate().request(request).build()).then(Mono.fromRunnable(() -> {
            ServerHttpResponse response = exchange.getResponse();
            HttpStatus statusCode = response.getStatusCode();
            logger.info("\n请求路径\t{}\n远程IP地址\t{}\n请求方法\t{}\n请求参数\t{}\n响应码\t{}", path, remoteAddress, method, builder.toString(), statusCode);
        }));
    }

    /*** *
     filter执行的优先级,值越小则优先级越大
    **/
    @Override
    public int getOrder() {
        return 1;
    }
}
